﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Sprite_Editor
{
    public partial class Form1 : Form
    {
        private OpenFileDialog openFileDialog;
        private SaveFileDialog saveFileDialog;
        private int beginX, beginY, endX, endY;
        private bool selecting;
        private String currFile, prevFile;
        private bool saved;
        private int prevState, prevFrame, prevAngle;
        private Hashtable durations;
        private float multiplier;

        public Form1()
        {
            InitializeComponent();

            openFileDialog = new OpenFileDialog();
            openFileDialog.RestoreDirectory = false;
            openFileDialog.InitialDirectory = Application.StartupPath;

            saveFileDialog = new SaveFileDialog();
            saveFileDialog.RestoreDirectory = false;
            saveFileDialog.InitialDirectory = Application.StartupPath;

            durations = new Hashtable();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            beginX = -1;
            beginY = -1;
            endX = -1;
            endY = -1;
            selecting = false;
            openFile(Application.StartupPath + @"\Sprites\calib.spr");
            multiplier = 1;
        }

        protected void Form1_Resize(object sender, EventArgs e)
        {
            picMain.Height = this.Height - 77;
            picMain.Width = this.Width - 280;

            lblAtlas.Left = this.Width - 256;
            txtAtlas.Left = lblAtlas.Left + lblAtlas.Width + 6;
            cmdBrowse.Left = txtAtlas.Left + txtAtlas.Width + 6;
            
            tabControl.Left = lblAtlas.Left + 3;
        }

        private void validateStates(object sender, EventArgs e)
        {
            ((TextBox) sender).Text = Convert.ToUInt16(((TextBox) sender).Text.ToString(), 10).ToString();
        }

        private void cmdBrowse_Click(object sender, EventArgs e)
        {
            Stream myStream;

            openFileDialog.Filter = "PNG files (*.png)|*.png|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 1;
                        
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                if ((myStream = openFileDialog.OpenFile()) != null)
                {
                    txtAtlas.Text = openFileDialog.FileName;
                    updateImage(this, null);
                    myStream.Close();
                }
            }

            openFileDialog.Reset();
        }

        private void deleteSelectedStateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saved = false;
            tabControl.TabPages.RemoveAt(tabControl.SelectedIndex);
        }

        private void addStateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saved = false;

            tabControl.TabPages.Add("New State");
            tabControl.SelectedTab = tabControl.TabPages[tabControl.TabPages.Count - 1];

            TabPage newTabPage = tabControl.SelectedTab;
            
            Label lblName = new Label();
            Label lblFrames = new Label();
            Label lblBottom = new Label();
            Label lblHeight = new Label();
            Label lblWidth = new Label();
            TextBox txtName = new TextBox();
            TextBox txtFrames = new TextBox();
            TextBox txtBottom = new TextBox();
            TextBox txtHeight = new TextBox();
            TextBox txtWidth = new TextBox();
            PictureBox picPreview = new PictureBox();
            Button cmdUp = new Button();
            Label lblPreviewFrame = new Label();
            Label lblPreviewAngle = new Label();
            Button cmdDown = new Button();
            TextBox txtAngle = new TextBox();
            TextBox txtFrame = new TextBox();
            CheckBox chkAngle = new CheckBox();
            CheckBox chkFrame = new CheckBox();

            newTabPage.Controls.Add(picPreview);
            newTabPage.Controls.Add(lblName);
            newTabPage.Controls.Add(lblFrames);
            newTabPage.Controls.Add(lblBottom);
            newTabPage.Controls.Add(lblHeight);
            newTabPage.Controls.Add(lblWidth);
            newTabPage.Controls.Add(txtName);
            newTabPage.Controls.Add(txtFrames);
            newTabPage.Controls.Add(txtBottom);
            newTabPage.Controls.Add(txtHeight);
            newTabPage.Controls.Add(txtWidth);
            newTabPage.Controls.Add(cmdUp);
            newTabPage.Controls.Add(lblPreviewFrame);
            newTabPage.Controls.Add(lblPreviewAngle);
            newTabPage.Controls.Add(cmdDown);
            newTabPage.Controls.Add(txtAngle);
            newTabPage.Controls.Add(txtFrame);
            newTabPage.Controls.Add(chkAngle);
            newTabPage.Controls.Add(chkFrame);
            newTabPage.Location = new System.Drawing.Point(4, 22);
            newTabPage.Name = "";
            newTabPage.Size = new System.Drawing.Size(220, 206);
            newTabPage.TabIndex = 0;
            newTabPage.Text = "New State";
            newTabPage.UseVisualStyleBackColor = true;

            ArrayList durs = new ArrayList();

            durations.Add(newTabPage, durs);

            // 
            // cmdDown
            // 
            cmdDown.Location = new System.Drawing.Point(6, 176);
            cmdDown.Name = "cmdDown";
            cmdDown.Size = new System.Drawing.Size(93, 23);
            cmdDown.TabIndex = 14;
            cmdDown.Text = "Slower";
            cmdDown.UseVisualStyleBackColor = true;
            cmdDown.Click += new System.EventHandler(slower);
            toolTip.SetToolTip(tabControl.SelectedTab.Controls["cmdDown"], "x1");
            // 
            // cmdUp
            // 
            cmdUp.Location = new System.Drawing.Point(6, 154);
            cmdUp.Name = "cmdUp";
            cmdUp.Size = new System.Drawing.Size(93, 23);
            cmdUp.TabIndex = 13;
            cmdUp.Text = "Faster";
            cmdUp.UseVisualStyleBackColor = true;
            cmdUp.Click += new System.EventHandler(faster);
            toolTip.SetToolTip(tabControl.SelectedTab.Controls["cmdUp"], "x1");
            // 
            // lblPreviewFrame
            // 
            lblPreviewFrame.AutoSize = true;
            lblPreviewFrame.Location = new System.Drawing.Point(3, 136);
            lblPreviewFrame.Name = "lblPreviewFrame";
            lblPreviewFrame.Size = new System.Drawing.Size(39, 13);
            lblPreviewFrame.TabIndex = 12;
            lblPreviewFrame.Text = "Frame:";
            lblPreviewFrame.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // lblPreviewAngle
            // 
            lblPreviewAngle.AutoSize = true;
            lblPreviewAngle.Location = new System.Drawing.Point(5, 116);
            lblPreviewAngle.Name = "lblPreviewAngle";
            lblPreviewAngle.Size = new System.Drawing.Size(37, 13);
            lblPreviewAngle.TabIndex = 11;
            lblPreviewAngle.Text = "Angle:";
            lblPreviewAngle.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // picPreview
            // 
            picPreview.Location = new System.Drawing.Point(105, 113);
            picPreview.Name = "picPreview";
            picPreview.Size = new System.Drawing.Size(100, 86);
            picPreview.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            picPreview.TabIndex = 10;
            picPreview.TabStop = false;
            // 
            // txtWidth
            // 
            txtWidth.Location = new System.Drawing.Point(105, 87);
            txtWidth.Name = "txtWidth";
            txtWidth.Size = new System.Drawing.Size(100, 20);
            txtWidth.TabIndex = 9;
            txtWidth.Text = "32";
            txtWidth.TextChanged += new System.EventHandler(valueChanged);
            // 
            // txtHeight
            // 
            txtHeight.Location = new System.Drawing.Point(105, 67);
            txtHeight.Name = "txtHeight";
            txtHeight.Size = new System.Drawing.Size(100, 20);
            txtHeight.TabIndex = 8;
            txtHeight.Text = "32";
            txtHeight.TextChanged += new System.EventHandler(valueChanged);
            // 
            // txtBottom
            // 
            txtBottom.Location = new System.Drawing.Point(105, 47);
            txtBottom.Name = "txtBottom";
            txtBottom.Size = new System.Drawing.Size(100, 20);
            txtBottom.TabIndex = 7;
            txtBottom.Text = "0";
            txtBottom.TextChanged += new System.EventHandler(valueChanged);
            // 
            // txtFrames
            // 
            txtFrames.Location = new System.Drawing.Point(105, 27);
            txtFrames.Name = "txtFrames";
            txtFrames.Size = new System.Drawing.Size(100, 20);
            txtFrames.TabIndex = 6;
            txtFrames.Text = "1";
            txtFrames.TextChanged += new System.EventHandler(framesChanged);
            framesChanged(txtFrames, null);
            // 
            // txtName
            // 
            txtName.Location = new System.Drawing.Point(105, 7);
            txtName.Name = "txtName";
            txtName.Size = new System.Drawing.Size(100, 20);
            txtName.TabIndex = 5;
            txtName.Text = "State 1";
            txtName.TextChanged += new System.EventHandler(updateStateName);
            // 
            // lblWidth
            // 
            lblWidth.AutoSize = true;
            lblWidth.Location = new System.Drawing.Point(61, 90);
            lblWidth.Name = "lblWidth";
            lblWidth.Size = new System.Drawing.Size(38, 13);
            lblWidth.TabIndex = 4;
            lblWidth.Text = "Width:";
            lblWidth.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // lblHeight
            // 
            lblHeight.AutoSize = true;
            lblHeight.Location = new System.Drawing.Point(58, 70);
            lblHeight.Name = "lblHeight";
            lblHeight.Size = new System.Drawing.Size(41, 13);
            lblHeight.TabIndex = 3;
            lblHeight.Text = "Height:";
            lblHeight.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // lblBottom
            // 
            lblBottom.AutoSize = true;
            lblBottom.Location = new System.Drawing.Point(56, 50);
            lblBottom.Name = "lblBottom";
            lblBottom.Size = new System.Drawing.Size(43, 13);
            lblBottom.TabIndex = 2;
            lblBottom.Text = "Bottom:";
            lblBottom.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // lblFrames
            // 
            lblFrames.AutoSize = true;
            lblFrames.Location = new System.Drawing.Point(3, 30);
            lblFrames.Name = "lblFrames";
            lblFrames.Size = new System.Drawing.Size(96, 13);
            lblFrames.TabIndex = 1;
            lblFrames.Text = "Number of Frames:";
            lblFrames.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // lblName
            // 
            lblName.AutoSize = true;
            lblName.Location = new System.Drawing.Point(61, 10);
            lblName.Name = "lblName";
            lblName.Size = new System.Drawing.Size(38, 13);
            lblName.TabIndex = 0;
            lblName.Text = "Name:";
            lblName.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // txtAngle
            // 
            txtAngle.Location = new System.Drawing.Point(48, 113);
            txtAngle.Name = "txtAngle";
            txtAngle.Size = new System.Drawing.Size(30, 20);
            txtAngle.TabIndex = 15;
            // 
            // txtFrame
            // 
            txtFrame.Location = new System.Drawing.Point(48, 133);
            txtFrame.Name = "txtFrame";
            txtFrame.Size = new System.Drawing.Size(30, 20);
            txtFrame.TabIndex = 16;
            // 
            // chkAngle
            // 
            chkAngle.Checked = true;
            chkAngle.AutoSize = true;
            chkAngle.Location = new System.Drawing.Point(84, 116);
            chkAngle.Name = "chkAngle";
            chkAngle.Size = new System.Drawing.Size(15, 14);
            chkAngle.TabIndex = 17;
            chkAngle.UseVisualStyleBackColor = true;
            // 
            // chkFrame
            // 
            chkFrame.Checked = true;
            chkFrame.AutoSize = true;
            chkFrame.Location = new System.Drawing.Point(84, 136);
            chkFrame.Name = "chkFrame";
            chkFrame.Size = new System.Drawing.Size(15, 14);
            chkFrame.TabIndex = 18;
            chkFrame.UseVisualStyleBackColor = true;

            updateImage(this, null);
        }

        private void updateStateName(object sender, EventArgs e)
        {
            saved = false;
            ((TextBox)sender).Parent.Text = ((TextBox)sender).Text;
        }

        private void updateImage(object sender, EventArgs e)
        {
            picMain.Image = createImage();
        }

        private Image createImage()
        {
            Image canvas;

            try
            {
                canvas = Bitmap.FromFile(txtAtlas.Text);
            }
            catch (Exception)
            {
                return null;
            }

            Graphics overlay = Graphics.FromImage(canvas);
            TabPage myTabPage = tabControl.SelectedTab;
            int frames, bottom, height, width;

            try
            {
                frames = Convert.ToInt32(((TextBox)myTabPage.Controls["txtFrames"]).Text);
                bottom = Convert.ToInt32(((TextBox)myTabPage.Controls["txtBottom"]).Text);
                height = Convert.ToInt32(((TextBox)myTabPage.Controls["txtHeight"]).Text);
                width = Convert.ToInt32(((TextBox)myTabPage.Controls["txtWidth"]).Text);

                for (int i = 0; i < 7; i++)
                {
                    for (int j = 0; j < frames; j++)
                    {
                        Color myColor = new Color();
                        myColor = (i + j) % 2 == 1 ? Color.FromArgb(127,255,0,0) : Color.FromArgb(127,0,0,255);
                        overlay.DrawRectangle(new Pen(myColor), i * width, canvas.Height - (bottom + (j + 1) * height), width - 1, height - 1);
                    }
                }
            }
            catch (Exception) 
            {
            }

            try 
            {
                int startX = beginX < endX ? beginX : endX;
                int startY = beginY < endY ? beginY : endY;
                int selWidth = Math.Abs(beginX - endX); 
                int selHeight = Math.Abs(beginY - endY);
                
                overlay.DrawRectangle(new Pen(Color.FromArgb(127, 0, 0, 0)), startX, startY, selWidth, selHeight);
            }
            catch (Exception)
            {
            }

            return canvas;
            
        }

        private void beginSelect(object sender, MouseEventArgs e)
        {
            if (picMain.Image == null)
                return;

            selecting = true;
            beginX = e.X;
            beginY = e.Y;
            endX = e.X;
            endY = e.Y;

            beginX = beginX > picMain.Image.Width - 1 ? picMain.Image.Width - 1 : (beginX < 1 ? 1 : beginX);
            beginY = beginY > picMain.Image.Height - 1 ? picMain.Image.Height - 1 : (beginY < 1 ? 1 : beginY);

            updateImage(this, null);
        }

        private void endSelect(object sender, MouseEventArgs e)
        {
            if (!selecting || picMain.Image == null)
                return;

            endX = e.X;
            endY = e.Y;
            selecting = false;

            endX = endX > picMain.Image.Width - 1 ? picMain.Image.Width - 1 : (endX < 0 ? 0 : endX);
            endY = endY > picMain.Image.Height - 1 ? picMain.Image.Height - 1 : (endY < 0 ? 0 : endY);

            tabControl.SelectedTab.Controls["txtBottom"].Text = (picMain.Image.Height - Math.Max(beginY, endY) - 1).ToString();
            tabControl.SelectedTab.Controls["txtWidth"].Text = Convert.ToInt32(Math.Max(beginX, endX) / 7).ToString();
            tabControl.SelectedTab.Controls["txtHeight"].Text = Convert.ToInt32(Math.Abs(beginY - endY) / Convert.ToInt32(tabControl.SelectedTab.Controls["txtFrames"].Text)).ToString();
            
            beginX = -1;
            beginY = -1;
            endX = -1;
            endY = -1;

            updateImage(this, null);
        }

        private void inSelect(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && selecting)
            {
                endX = e.X;
                endY = e.Y;

                endX = endX > picMain.Image.Width - 1 ? picMain.Image.Width - 1 : (endX < 0 ? 0 : endX);
                endY = endY > picMain.Image.Height - 1 ? picMain.Image.Height - 1 : (endY < 0 ? 0 : endY);

                updateImage(this, null);
                //MessageBox.Show(beginX.ToString() + "," + beginY.ToString() + " -> " + endX.ToString() + "," + endY.ToString());
            }
            else if (selecting)
            {
                selecting = false;
            }
        }

        private void autoResizeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                this.Height = picMain.Image.Height + 157;
                this.Width = (picMain.Image.Width + 12) * 2;
            }
            catch (Exception)
            {
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialog.Filter = "Sprite files (*.spr)|*.spr|All files (*.*)|*.*";
            saveFileDialog.FilterIndex = 1;
            saveFileDialog.FileName = Path.GetFileNameWithoutExtension(txtAtlas.Text) + ".spr";

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                saveFile(saveFileDialog.FileName);
            }

            saveFileDialog.Reset();

            saved = true;
            this.Text = "Sprite Editor - " + Path.GetFileNameWithoutExtension(currFile) + ".spr";
        }

        private void saveFile(string file)
        {
            try
            {
                StringBuilder output = new StringBuilder();
                StreamWriter myStream;

                if ((myStream = new StreamWriter(file)) != null)
                {
                    output.AppendLine("Textures/" + Path.GetFileNameWithoutExtension(txtAtlas.Text) + ".png");
                    output.AppendLine(tabControl.TabCount.ToString());

                    for (int i = 0; i < tabControl.TabCount; i++)
                    {
                        output.AppendLine(((TextBox)tabControl.TabPages[i].Controls["txtName"]).Text.Trim());
                        output.AppendLine(((TextBox)tabControl.TabPages[i].Controls["txtFrames"]).Text.Trim());

                        ArrayList durs = (ArrayList)durations[tabControl.TabPages[i]];

                        foreach (TrackBar tb in durs)
                        {
                            output.AppendLine(((float) tb.Value / 1000).ToString());
                        }

                        output.AppendLine(((TextBox)tabControl.TabPages[i].Controls["txtBottom"]).Text.Trim());
                        output.AppendLine(((TextBox)tabControl.TabPages[i].Controls["txtHeight"]).Text.Trim());
                        output.AppendLine(((TextBox)tabControl.TabPages[i].Controls["txtWidth"]).Text.Trim());
                    }

                    output.Replace("\r", "");
                    myStream.Write(output.ToString());
                    myStream.Close();

                    saved = true;
                    currFile = file;
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Unable to save " + file + ". Unknown error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void openObjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!saved)
            {
                DialogResult myResult = MessageBox.Show("Save changes to current sprite?", "Sprite Editor", MessageBoxButtons.YesNoCancel);

                if (myResult == DialogResult.Yes)
                {
                    saveToolStripMenuItem_Click(this, null);
                }
                else if (myResult == DialogResult.Cancel)
                {
                    return;
                }
            }

            openFileDialog.Filter = "Sprite files (*.spr)|*.spr|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 1;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                openFile(openFileDialog.FileName);
            }

            openFileDialog.Reset();
        }

        private void openFile(string file)
        {
            StreamReader myStream;

            if ((myStream = new StreamReader(file)) != null)
            {
                try
                {
                    clearAll();

                    String line;

                    line = myStream.ReadLine();
                    txtAtlas.Text = Path.GetDirectoryName(file).Replace("Sprites", "") + line;
                    updateImage(this, null);

                    line = myStream.ReadLine();
                    int states = Convert.ToInt32(line);
                    tabControl.TabPages.Clear();

                    for (int i = 0; i < states; i++)
                    {
                        addStateToolStripMenuItem_Click(this, null);
                        ((TextBox)tabControl.TabPages[i].Controls["txtName"]).Text = myStream.ReadLine();
                        ((TextBox)tabControl.TabPages[i].Controls["txtFrames"]).Text = myStream.ReadLine();

                        framesChanged(tabControl.TabPages[i].Controls["txtFrames"], null);

                        ArrayList durs = (ArrayList) durations[tabControl.TabPages[i]];

                        foreach (TrackBar tb in durs)
                            tb.Value = (int) (Convert.ToDouble(myStream.ReadLine()) * 1000);

                        ((TextBox)tabControl.TabPages[i].Controls["txtBottom"]).Text = myStream.ReadLine();
                        ((TextBox)tabControl.TabPages[i].Controls["txtHeight"]).Text = myStream.ReadLine();
                        ((TextBox)tabControl.TabPages[i].Controls["txtWidth"]).Text = myStream.ReadLine();
                    }

                    updateImage(this, null);
                    myStream.Close();

                    saved = true;
                    currFile = file;
                    autoResizeToolStripMenuItem_Click(this, null);

                    this.Text = "Sprite Editor - " + Path.GetFileNameWithoutExtension(currFile) + ".spr";
                }
                catch (Exception e)
                {
                    clearAll();
                    saved = true;
                    currFile = file;
                    MessageBox.Show("Unable to open " + file + ". Error: " + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!saved && currFile != null)
            {
                saveFile(currFile);
            }
            else if (!saved)
            {
                saveAsToolStripMenuItem_Click(sender, e);
            }
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void valueChanged(object sender, EventArgs e)
        {
            saved = false;
            updateImage(sender, e);
        }

        private void framesChanged(object sender, EventArgs e)
        {
            try
            {
                ArrayList durs = (ArrayList)durations[tabControl.SelectedTab];
                
                int old_count = durs.Count;
                int new_count = Convert.ToInt32(((TextBox)sender).Text);
                bool scroll = new_count > 5 && old_count < 6;
                bool unscroll = old_count > 5 && new_count < 6;

                while (old_count < new_count)
                {
                    TrackBar newTrackBar = new TrackBar();
                    newTrackBar.Orientation = Orientation.Vertical;
                    newTrackBar.TickStyle = TickStyle.TopLeft;
                    newTrackBar.Minimum = 1;
                    newTrackBar.Maximum = 1000;
                    newTrackBar.SmallChange = 1;
                    newTrackBar.LargeChange = 100;
                    newTrackBar.TickFrequency = 100;
                    newTrackBar.Value = 1000 / new_count;
                    newTrackBar.ValueChanged += new EventHandler(trackChanged);
                    toolTip.SetToolTip(newTrackBar, old_count.ToString() + ": " + newTrackBar.Value.ToString());

                    durs.Add(newTrackBar);
                    tabControl.SelectedTab.Controls.Add(newTrackBar);
                    
                    old_count++;
                }

                while (old_count > new_count)
                {
                    TrackBar oldTrackBar = (TrackBar)durs[old_count - 1];
                    tabControl.SelectedTab.Controls.Remove(oldTrackBar);
                    durs.RemoveAt(old_count - 1);

                    old_count--;
                }

                if (scroll)
                {
                    HScrollBar newScroll = new HScrollBar();
                    newScroll.Name = "HSCROLL";
                    newScroll.Location = new System.Drawing.Point(0, 269);
                    newScroll.Size = new System.Drawing.Size(220, 17);
                    newScroll.Minimum = 1;
                    newScroll.Maximum = new_count;
                    newScroll.Value = 1;
                    newScroll.LargeChange = 5;
                    newScroll.ValueChanged += new System.EventHandler(scrollChanged);

                    tabControl.SelectedTab.Controls.Add(newScroll);
                }

                if (unscroll)
                    tabControl.SelectedTab.Controls.RemoveByKey("HSCROLL");

                if (new_count > 5)
                {
                    ((HScrollBar)tabControl.SelectedTab.Controls["HSCROLL"]).Maximum = new_count;

                    for (int i = 0; i < new_count; i++)
                    {
                        ((TrackBar)durs[i]).Size = new System.Drawing.Size(45, 57);
                        
                        int last = 4 + ((HScrollBar)tabControl.SelectedTab.Controls["HSCROLL"]).Value;

                        if (i < last)
                        {
                            ((TrackBar)durs[i]).Visible = true;
                            ((TrackBar)durs[i]).Location = new System.Drawing.Point(208 - (last - i) * 40, 205);
                        }
                        else
                            ((TrackBar)durs[i]).Visible = false;
                    }
                }
                else
                {
                    for (int i = 0; i < new_count; i++)
                    {
                        ((TrackBar)durs[i]).Size = new System.Drawing.Size(45, 74);
                        ((TrackBar)durs[i]).Location = new System.Drawing.Point(8 + i * 40, 205);
                    }
                }

                durations.Remove(tabControl.SelectedTab);
                durations.Add(tabControl.SelectedTab, durs);
            }
            catch (Exception)
            {
            }

            valueChanged(sender, e);
        }

        private void trackChanged(object sender, EventArgs e)
        {
            saved = false;

            ArrayList durs = (ArrayList)durations[tabControl.SelectedTab];
            
            int index = durs.IndexOf(sender);

            toolTip.SetToolTip((TrackBar) sender, index.ToString() + ": " + ((TrackBar)sender).Value.ToString());
        }

        private void scrollChanged(object sender, EventArgs e)
        {
            ArrayList durs = (ArrayList) durations[tabControl.SelectedTab];

            for (int i = 0; i < durs.Count; i++)
            {
                ((TrackBar)durs[i]).Size = new System.Drawing.Size(45, 57);
                
                int last = 4 + ((HScrollBar)tabControl.SelectedTab.Controls["HSCROLL"]).Value;

                if (i < last)
                {
                    ((TrackBar)durs[i]).Visible = true;
                    ((TrackBar)durs[i]).Location = new System.Drawing.Point(208 - (last - i) * 40, 205);
                }
                else
                    ((TrackBar)durs[i]).Visible = false;
            }
        }
        
        private void newObjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!saved)
            {
                DialogResult myResult = MessageBox.Show("Save changes to current sprite?", "Sprite Editor", MessageBoxButtons.YesNoCancel);

                if (myResult == DialogResult.Yes)
                {
                    saveToolStripMenuItem_Click(this, null);
                }
                else if (myResult == DialogResult.Cancel)
                {
                    return;
                }
            }

            clearAll();

            saved = true;
            currFile = null;
        }

        private void clearAll()
        {
            txtAtlas.Text = "";
            
            tabControl.TabPages.Clear();
            toolTip.RemoveAll();

            addStateToolStripMenuItem_Click(this, null);

            /*
            ((TextBox)tabControl.TabPages[0].Controls["txtName"]).Text = "State 1";
            ((TextBox)tabControl.TabPages[0].Controls["txtFrames"]).Text = "1";
            ((TextBox)tabControl.TabPages[0].Controls["txtBottom"]).Text = "0";
            ((TextBox)tabControl.TabPages[0].Controls["txtHeight"]).Text = "0";
            ((TextBox)tabControl.TabPages[0].Controls["txtWidth"]).Text = "0";
            */

            updateImage(this, null);
        }

        private void aboutObjectEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Sprite Editor v1.0 is designed to support the development of LongDawg, LoneWolf and LoneWolf-R. © 2010 Luv & Caleb.", "About Sprite Editor", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!saved)
            {
                DialogResult myResult = MessageBox.Show("Save changes to current sprite?", "Sprite Editor", MessageBoxButtons.YesNoCancel);

                if (myResult == DialogResult.Yes)
                {
                    saveToolStripMenuItem_Click(this, null);
                }
                else if (myResult == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }

        private void updatePreview(object sender, EventArgs e)
        {
            try
            {
                if (picMain.Image == null)
                    return;

                if (currFile != prevFile)
                {
                    prevFile = currFile;
                    prevState = tabControl.SelectedIndex;
                    prevAngle = ((CheckBox)tabControl.SelectedTab.Controls["chkAngle"]).Checked ? 0 : Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtAngle"]).Text);
                    prevFrame = ((CheckBox)tabControl.SelectedTab.Controls["chkFrame"]).Checked ? 0 : Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtFrame"]).Text);
                }
                else if (prevState != tabControl.SelectedIndex)
                {
                    prevState = tabControl.SelectedIndex;
                    prevAngle = ((CheckBox)tabControl.SelectedTab.Controls["chkAngle"]).Checked ? 0 : Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtAngle"]).Text);
                    prevFrame = ((CheckBox)tabControl.SelectedTab.Controls["chkFrame"]).Checked ? 0 : Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtFrame"]).Text);
                }
                else
                {
                    bool frame = ((CheckBox)tabControl.SelectedTab.Controls["chkFrame"]).Checked;
                    bool angle = ((CheckBox)tabControl.SelectedTab.Controls["chkAngle"]).Checked;

                    if (!frame)
                        prevFrame = Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtFrame"]).Text);

                    if (!angle)
                        prevAngle = Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtAngle"]).Text);

                    if (frame) 
                        prevFrame++;
                    else if (angle)
                        prevAngle++;

                    if (prevFrame >= Convert.ToInt32(((TextBox)tabControl.SelectedTab.Controls["txtFrames"]).Text) || prevFrame < 0)
                    {
                        prevFrame = 0;
                        prevAngle = frame && angle ? prevAngle + 1 : prevAngle;
                    }

                    if (prevAngle > 6 || prevAngle < 0)
                    {
                        prevAngle = 0;
                        prevFrame = frame ? 0 : prevFrame;
                    }
                }

                ((PictureBox)tabControl.SelectedTab.Controls["picPreview"]).Image = preview(prevAngle, prevFrame);
                ((TextBox)tabControl.SelectedTab.Controls["txtFrame"]).Text = prevFrame.ToString();
                ((TextBox)tabControl.SelectedTab.Controls["txtAngle"]).Text = prevAngle.ToString();

                ArrayList durs = (ArrayList)durations[tabControl.SelectedTab];

                timer.Interval = (int)(((TrackBar)durs[prevFrame]).Value / multiplier);
            }
            catch (Exception)
            {
            }
        }

        private Image preview(int angle, int frame)
        {
            Image canvas = picMain.Image;

            try
            {
                TabPage myTabPage = tabControl.SelectedTab;

                int frames = Convert.ToInt32(((TextBox)myTabPage.Controls["txtFrames"]).Text);
                int bottom = Convert.ToInt32(((TextBox)myTabPage.Controls["txtBottom"]).Text);
                int height = Convert.ToInt32(((TextBox)myTabPage.Controls["txtHeight"]).Text);
                int width = Convert.ToInt32(((TextBox)myTabPage.Controls["txtWidth"]).Text);

                int X = width * angle;
                int Y = canvas.Height - (bottom + (frame + 1) * height);
                Rectangle myRect = new Rectangle(X, Y, width, height);
                canvas = new Bitmap(canvas).Clone(myRect, System.Drawing.Imaging.PixelFormat.DontCare);
            }
            catch (Exception)
            {
                return null;
            }

            return canvas;            
        }

        private void faster(object sender, EventArgs e)
        {
            //timer.Interval = Math.Max(Convert.ToInt32(timer.Interval * 0.8 - 1), 40);            
            multiplier = (float) Math.Round(Math.Min(multiplier + 0.2, 5), 2);
            toolTip.SetToolTip(tabControl.SelectedTab.Controls["cmdUp"], "x" + multiplier.ToString());
            toolTip.SetToolTip(tabControl.SelectedTab.Controls["cmdDown"], "x" + multiplier.ToString());
        }

        private void slower(object sender, EventArgs e)
        {
            //timer.Interval = Math.Min(Convert.ToInt32(timer.Interval * 1.25 + 1), 2000);            
            multiplier = (float) Math.Round(Math.Max(multiplier - 0.2, 0.2), 2);
            toolTip.SetToolTip(tabControl.SelectedTab.Controls["cmdUp"], "x" + multiplier.ToString());
            toolTip.SetToolTip(tabControl.SelectedTab.Controls["cmdDown"], "x" + multiplier.ToString());
        }

    }
}
